home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 317 / asmsrc / as.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-20  |  8.7 KB  |  292 lines

  1. /* as.c - GAS main program. */
  2.  
  3. /* Copyright (C) 1987 Free Software Foundation, Inc.
  4.  
  5. This file is part of Gas, the GNU Assembler.
  6.  
  7. The GNU assembler is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY.  No author or distributor
  9. accepts responsibility to anyone for the consequences of using it
  10. or for whether it serves any particular purpose or works at all,
  11. unless he says so in writing.  Refer to the GNU Assembler General
  12. Public License for full details.
  13.  
  14. Everyone is granted permission to copy, modify and redistribute
  15. the GNU Assembler, but only under the conditions described in the
  16. GNU Assembler General Public License.  A copy of this license is
  17. supposed to have been given to you along with the GNU Assembler
  18. so you can know your rights and responsibilities.  It should be
  19. in a file named COPYING.  Among other things, the copyright
  20. notice and this notice must be preserved on all copies.  */
  21.  
  22. /*
  23.  * Main program for AS; a 32-bit assembler of GNU.
  24.  * Understands command arguments.
  25.  * Has a few routines that don't fit in other modules because they
  26.  * are shared.
  27.  *
  28.  *
  29.  *            bugs
  30.  *
  31.  * : initialisers
  32.  *    Since no-one else says they will support them in future: I
  33.  * don't support them now.
  34.  *
  35.  */
  36.  
  37. #define COMMON
  38. #include "as.h"
  39. #include "struc-symbol.h"
  40. #include "write.h"
  41.         /* Warning!  This may have some slightly strange side effects
  42.            if you try to compile two or more assemblers in the same
  43.            directory!
  44.          */
  45.  
  46. static char * gdb_symbol_file_name;
  47.  
  48. char *myname;        /* argv[0] */
  49. extern char version_string[];
  50.  
  51. main(argc,argv)
  52. int    argc;
  53. char    **argv;
  54. {
  55.     int    work_argc;    /* variable copy of argc */
  56.     char    **work_argv;    /* variable copy of argv */
  57.     char    *arg;        /* an arg to program */
  58.     char    a;        /* an arg flag (after -) */
  59.     char    *temp_file_name;    /* file name for -t option */
  60.  
  61.     char    *stralloc();    /* Make a (safe) copy of a string. */
  62.     long int gdb_begin();
  63.     void    symbol_begin();
  64.     void    read_begin();
  65.     void    write_object_file();
  66.  
  67.     myname=argv[0];
  68.     bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  69.     out_file_name    = "a.out";    /* default .o file */
  70.     symbol_begin();        /* symbols.c */
  71.     subsegs_begin();        /* subsegs.c */
  72.     read_begin();            /* read.c */
  73.     md_begin();            /* MACHINE.c */
  74.     input_scrub_begin();        /* input_scrub.c */
  75.     gdb_symbol_file_name = 0;
  76.     /*
  77.      * Parse arguments, but we are only interested in flags.
  78.      * When we find a flag, we process it then make it's argv[] NULL.
  79.      * This helps any future argv[] scanners avoid what we processed.
  80.      * Since it is easy to do here we interpret the special arg "-"
  81.      * to mean "use stdin" and we set that argv[] pointing to "".
  82.      * After we have munged argv[], the only things left are source file
  83.      * name(s) and ""(s) denoting stdin. These file names are used
  84.      * (perhaps more than once) later.
  85.      */
  86.     work_argc = argc-1;        /* don't count argv[0] */
  87.     work_argv = argv+1;        /* skip argv[0] */
  88.     for (;work_argc--;work_argv++) {
  89.         arg = * work_argv;    /* work_argv points to this argument */
  90.  
  91.         if (*arg!='-')        /* Filename. We need it later. */
  92.             continue;    /* Keep scanning args looking for flags. */
  93.         if (arg[1] == '-' && arg[2] == 0) {
  94.             /* "--" as an argument means read STDIN */
  95.             /* on this scan, we don't want to think about filenames */
  96.             * work_argv = "";    /* Code that means 'use stdin'. */
  97.             continue;
  98.         }
  99.                 /* This better be a switch. */
  100.         arg ++;        /* -> letter. */
  101.  
  102.         while (a = * arg)  {/* scan all the 1-char flags */
  103.  
  104.             /* Note that for reasons too complicated to go into
  105.                here, both the VAX and the 68020 acceopt
  106.                (and ignore) thise flags.  Of course, anyone who
  107.                does -m68020 on the vax is VERY confused
  108.              */
  109.             if(!strcmp(&arg[0],"mc68020") || !strcmp(&arg[0],"m68020")) {
  110.                 *work_argv=NULL;
  111.                 break;
  112.             }
  113.  
  114.             if(!strcmp(&arg[0],"v") || !strcmp(&arg[0],"version")) {
  115.                 fprintf(stderr,version_string);
  116.                 *work_argv=NULL;
  117.                 break;
  118.             }
  119.  
  120.             arg ++;    /* arg -> after letter. */
  121.             a &= 0x7F;    /* ascii only please */
  122.             if (flagseen[a])
  123.                 as_warn("%s: Flag option -%c has already been seen!",myname,a);
  124.             flagseen[a] = TRUE;
  125.             switch (a) {
  126.             case 'd':
  127.                 as_warn("%s: Displacement length %s. ignored! GNU is NOT Un*x!",myname,arg);
  128.                 break;
  129.  
  130.             case 'f':
  131.                 break;    /* -f means fast - no need for "app" preprocessor. */
  132.  
  133.             case 'D':
  134.                 /* DEBUG is implemented: it debugs different */
  135.                 /* things to other people's assemblers. */
  136.                 break;
  137.  
  138.             case 'G':    /* GNU AS switch: include gdbsyms. */
  139.                 if (*arg)    /* Rest of argument is file-name. */
  140.                     gdb_symbol_file_name = stralloc (arg);
  141.                 else if (work_argc) {    /* Next argument is file-name. */
  142.                     work_argc --;
  143.                     * work_argv = NULL; /* Not a source file-name. */
  144.                     gdb_symbol_file_name = * ++ work_argv;
  145.                 } else
  146.                     as_warn( "%s: I expected a filename after -G",myname);
  147.                 arg = "";    /* Finished with this arg. */
  148.                 break;
  149.  
  150.             case 'J':
  151.                 as_warn("%s: I can do better than -J!",myname);
  152.                 break;
  153.  
  154.             case 'L': /* -L means keep L* symbols */
  155.                 break;
  156.  
  157.             case 'l':    /* -l means keep external to 2 bit offset
  158.                        rather than 16 bit one */
  159.                 break;
  160.             case 'o':
  161.                 if (*arg)    /* Rest of argument is object file-name. */
  162.                     out_file_name = stralloc (arg);
  163.                 else if (work_argc) {    /* Want next arg for a file-name. */
  164.                     * work_argv = NULL; /* This is not a file-name. */
  165.                     work_argc--;
  166.                     out_file_name = * ++ work_argv;
  167.                 } else
  168.                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  169.                 arg = "";    /* Finished with this arg. */
  170.                 break;
  171.  
  172.             case 'R':
  173.                 /* -R means put data into text segment */
  174.                 break;
  175.  
  176.             case 'S':
  177.                 break;    /* SYMBOL TABLE not implemented */
  178.  
  179.             case 't':
  180.                 if (*arg)    /* Rest of argument is filename. */
  181.                     temp_file_name = stralloc (arg);
  182.                 else if (work_argc) {
  183.                     * work_argv = NULL; /* Remember this is not a file-name. */
  184.                     work_argc--;
  185.                     temp_file_name = *++work_argv;
  186.                 } else {
  187.                     as_warn("%s: I expected a filename after -t.",myname);
  188.                     temp_file_name = "{absent}";
  189.                 }
  190.                 as_warn("%s: I don't need or use temp. file \"%s\".",myname,temp_file_name);
  191.                 arg = "";    /* Finished with this arg. */
  192.                 break;
  193.  
  194.             case 'T':
  195.                 break;    /* TOKEN TRACE not implemented */
  196.  
  197.             case 'V':
  198.                 as_warn("%s: I don't use an interpass file! -V ignored",myname);
  199.                 break;
  200.  
  201.             case 'W':
  202.                 /* -W means don't warn about things */
  203.                 break;
  204.  
  205.             default:
  206.                 as_warn("%s: I don't understand '%c' flag!",myname,a);
  207.                 break;
  208.             }
  209.         }
  210.         /*
  211.          * We have just processed a "-..." arg, which was not a
  212.          * file-name. Smash it so the
  213.          * things that look for filenames won't ever see it.
  214.          *
  215.          * Whatever work_argv points to, it has already been used
  216.          * as part of a flag, so DON'T re-use it as a filename.
  217.          */
  218.         *work_argv = NULL; /* NULL means 'not a file-name' */
  219.     }
  220.     if (gdb_begin(gdb_symbol_file_name) == 0)
  221.         flagseen ['G'] = 0;    /* Don't do any gdbsym stuff. */
  222.     /* Here with flags set up in flagseen[]. */
  223.     perform_an_assembly_pass(argc,argv); /* Assemble it. */
  224.     if (seen_at_least_1_file())
  225.         write_object_file();/* relax() addresses then emit object file */
  226.     input_scrub_end();
  227.     md_end();            /* MACHINE.c */
  228.     exit(0);            /* WIN */
  229. }
  230.  
  231.  
  232. /*            perform_an_assembly_pass()
  233.  *
  234.  * Here to attempt 1 pass over each input file.
  235.  * We scan argv[*] looking for filenames or exactly "" which is
  236.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  237.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  238.  * expressions of the form (unknown value)+-(unknown value).
  239.  *
  240.  * Note the un*x semantics: there is only 1 logical input file, but it
  241.  * may be a catenation of many 'physical' input files.
  242.  */
  243. perform_an_assembly_pass (argc, argv)
  244. int    argc;
  245. char **    argv;
  246. {
  247.     char *    buffer;        /* Where each bufferful of lines will start. */
  248.     void    read_a_source_file();
  249.  
  250.     text_fix_root        = NULL;
  251.     data_fix_root        = NULL;
  252.     need_pass_2        = FALSE;
  253.  
  254.     argv++;            /* skip argv[0] */
  255.     argc--;            /* skip argv[0] */
  256.     while (argc--) {
  257.         if (*argv) {        /* Is it a file-name argument? */
  258.             /* argv -> "" if stdin desired, else -> filename */
  259.             if (buffer = input_scrub_new_file (*argv) )
  260.                 read_a_source_file(buffer);
  261.         }
  262.         argv++;            /* completed that argv */
  263.     }
  264. }
  265.  
  266. /*
  267.  *            stralloc()
  268.  *
  269.  * Allocate memory for a new copy of a string. Copy the string.
  270.  * Return the address of the new string. Die if there is any error.
  271.  */
  272.  
  273. char *
  274. stralloc (str)
  275. char *    str;
  276. {
  277.     register char *    retval;
  278.     register long int    len;
  279.  
  280.     len = strlen (str) + 1;
  281.     retval = xmalloc (len);
  282.     (void)strcpy (retval, str);
  283.     return (retval);
  284. }
  285.  
  286. lose()
  287. {
  288.     as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  289. }
  290.  
  291. /* end: as.c */
  292.